﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LibraryONTrack.dto;
using System.ComponentModel;
using LibraryONTrack.dao;

namespace LibraryONTrack.BAL
{

	[Serializable]
	public class RosterManagerException : Exception
	{
		public Roster Roster { get; set; }
		public Teacher Teacher { get; set; }
		public RosterManagerException() { }
		public RosterManagerException(string message) : base(message) { }
		public RosterManagerException(string message, Exception inner) : base(message, inner) { }
		public RosterManagerException(string message, Teacher teacher) : base(message) { Teacher = teacher; }
		protected RosterManagerException(
		System.Runtime.Serialization.SerializationInfo info,
		System.Runtime.Serialization.StreamingContext context)
			: base(info, context) { }
	}

	public class RosterManagerAssignedToAnotherException : RosterManagerException
	{
		public RosterManagerAssignedToAnotherException() : base() { }
		public RosterManagerAssignedToAnotherException(string message) : base(message) { }
		public RosterManagerAssignedToAnotherException(string message, Exception inner) : base(message, inner) { }
		public RosterManagerAssignedToAnotherException(string message, Teacher teacher) : base(message) { Teacher = teacher; }
	}


	public class RosterManager
	{
		public RosterManager()
		{

		}

		public BindingList<Roster> GetAll()
		{
			BindingList<Roster> rosters = new BindingList<Roster>();
			foreach (Teacher teacher in RosterDAO.GetAllTeachers())
			{
				rosters.Add(new Roster(teacher, new StudentDAO().GetAllStudents(teacher.Id)));
			}
			return rosters;
		}

		/// <summary>
		/// Returns a roster for the named teacher or exception if teacher does not exist
		/// </summary>
		/// <param name="teacherName"></param>
		/// <returns></returns>
		public Roster GetRoster(string teacherName)
		{
			Teacher teacher = new TeacherDAO().GetByName(teacherName);
			if (teacher == null)
			{
				throw new RosterManagerException("No roster for '" + teacherName + "'");
			}

			Roster roster = new Roster(teacher, new StudentDAO().GetAllStudents(teacher.Id));
			return roster;
		}

		//public Teacher getRoster(string teacherName)
		//{
		//  Teacher teacher = new TeacherDAO().GetByName(teacherName);
		//  if (teacher == null)
		//  {
		//    throw new RosterException("No roster for '"+teacherName+"'");
		//  }
		//  return teacher;
		//}

		public List<Student> getRosterStudents(Teacher teacher)
		{
			return new StudentDAO().GetAllStudents(teacher.Id);
		}

		public Teacher getRoster(long teacherId)
		{
			return (new TeacherDAO().GetById(teacherId));
		}

		public Roster AddRoster(string teacherName)
		{
			Roster roster = null;
			try
			{
				roster = GetRoster(teacherName);
				throw new RosterManagerException("Roster already exists for '" + teacherName + "'");
			}
			catch (Exception)
			{
				return GetRoster(new TeacherDAO().AddTeacher(teacherName).Name);
			}
		}

		public Student AddRosterStudent(Roster roster, string studentName)
		{
			// Check if the student is already assigned to a roster
			Student student = new StudentDAO().GetStudent(studentName);
			if (student != null)
			{
				// Found student. See if their already assigned to this roster.
				if (student.TeacherId == roster.Teacher.Id)
				{
					throw new RosterManagerException("Student is already assigned to this roster.", roster.Teacher);
				}
				throw new RosterManagerAssignedToAnotherException("Student is assigned to another roster", new TeacherDAO().GetById(student.TeacherId));
			}

			// Add student to current roster
			student = new StudentDAO().Insert(studentName, roster.Teacher.Id);
			roster.Students.Add(student);
			return (student);
		}

		public void delRoster(Teacher teacher)
		{
			new TeacherDAO().delTeacher(teacher);
		}



	}
}
